/*
 * Powered By [rapid-framework]
 * Web Site: http://www.rapid-framework.org.cn
 * Google Code: http://code.google.com/p/rapid-framework/
 * Since 2008 - 2019
 */

package net.dreamlu.db.qo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Order;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.hibernate.criterion.MatchMode;
import org.springframework.data.jpa.domain.Specification;
import net.dreamlu.db.po.*;
/**
 *
 * @author lambert.wang email:lambert.wang(a)crediteyes.com
 * @version 1.0
 * @since 1.0
 */
public class PersistentLoginsQuery extends PersistentLogins implements Serializable {
    private static final long serialVersionUID = 3148176768559230877L;
    

	/** username */
	private String likeUsernameWithStart;
	private String likeUsernameWithEnd;
	private String likeUsernameWithExact;
	private String likeUsernameWithAnywhere;
	private java.lang.String username;	
	private java.lang.String notEqUsername;	
	/** series */
	private String likeSeriesWithStart;
	private String likeSeriesWithEnd;
	private String likeSeriesWithExact;
	private String likeSeriesWithAnywhere;
	private java.lang.String series;	
	private java.lang.String notEqSeries;	
	/** token */
	private String likeTokenWithStart;
	private String likeTokenWithEnd;
	private String likeTokenWithExact;
	private String likeTokenWithAnywhere;
	private java.lang.String token;	
	private java.lang.String notEqToken;	
	/** lastUsed */
	private java.time.LocalDateTime lastUsedBegin;
	private java.time.LocalDateTime lastUsedEnd;	
	private java.time.LocalDateTime lastUsed;	
	private java.time.LocalDateTime notEqLastUsed;	
	
	/*********** 系统属性，自动赋值 *********/
	private MatchMode likeusername;
	private boolean isUsername;
	private boolean isNotEqUsername;
	private MatchMode likeseries;
	private boolean isSeries;
	private boolean isNotEqSeries;
	private MatchMode liketoken;
	private boolean isToken;
	private boolean isNotEqToken;
	private boolean isLastUsedBegin;
	private boolean isLastUsedEnd;
	private boolean isLastUsed;
	private boolean isNotEqLastUsed;
	public MatchMode getLikeUsername() {
		return this.likeusername;
	}
	public String getLikeUsernameWithStart() {
		return this.likeUsernameWithStart;
	}
	public void setLikeUsernameWithStart(String username) {	
		setUsername(username);
		setLikeUsername(MatchMode.START);
	}
	public String getLikeUsernameWithEnd() {
		return this.likeUsernameWithEnd;
	}
	public void setLikeUsernameWithEnd(String username) {	
		setUsername(username);
		setLikeUsername(MatchMode.END);
	}
	public String getLikeUsernameWithExact() {
		return this.likeUsernameWithExact;
	}
	public void setLikeUsernameWithExact(String username) {	
		setUsername(username);
		setLikeUsername(MatchMode.EXACT);
	}
	public String getLikeUsernameWithAnywhere() {
		return this.likeUsernameWithAnywhere;
	}
	public void setLikeUsernameWithAnywhere(String username) {	
		setUsername(username);
		setLikeUsername(MatchMode.ANYWHERE);
	}
	private void setLikeUsername(MatchMode matchMode) {		
		this.likeusername = matchMode;
	}
	public java.lang.String getUsername() {
		return this.username;
	}
	
	public void setUsername(java.lang.String value) {		
		this.username = value;
		this.isUsername = true;
	}
	public boolean hasUsername() {
		return this.isUsername;
	}
	public java.lang.String getNotEqUsername() {
		return this.notEqUsername;
	}
	public void setNotEqUsername(java.lang.String username) {
		this.notEqUsername = username;
		this.isNotEqUsername = true;
	}
	public boolean hasNotEqUsername() {
		return this.isNotEqUsername;
	}
	// IN or notIN
	private List<java.lang.String>	inCriterionUsername;
	private List<java.lang.String>	notInCriterionUsername;
	public void setInUsername(boolean isIn,List<java.lang.String> usernames){
		if(isIn){
			inCriterionUsername = usernames;
		}else{
			notInCriterionUsername = usernames;
		}
	}
	public List<java.lang.String> getInUsername() {
		return inCriterionUsername;
	}
	public List<java.lang.String> getNotInUsername() {
		return notInCriterionUsername;
	}
	
	//Null or NotNull
	private Boolean nullCriterionUsername;
	public void setNullUsername(boolean isNull){
			nullCriterionUsername = isNull;
	}
	public Boolean getNullUsername(){
		return nullCriterionUsername;
	} 
	
	public MatchMode getLikeSeries() {
		return this.likeseries;
	}
	public String getLikeSeriesWithStart() {
		return this.likeSeriesWithStart;
	}
	public void setLikeSeriesWithStart(String series) {	
		setSeries(series);
		setLikeSeries(MatchMode.START);
	}
	public String getLikeSeriesWithEnd() {
		return this.likeSeriesWithEnd;
	}
	public void setLikeSeriesWithEnd(String series) {	
		setSeries(series);
		setLikeSeries(MatchMode.END);
	}
	public String getLikeSeriesWithExact() {
		return this.likeSeriesWithExact;
	}
	public void setLikeSeriesWithExact(String series) {	
		setSeries(series);
		setLikeSeries(MatchMode.EXACT);
	}
	public String getLikeSeriesWithAnywhere() {
		return this.likeSeriesWithAnywhere;
	}
	public void setLikeSeriesWithAnywhere(String series) {	
		setSeries(series);
		setLikeSeries(MatchMode.ANYWHERE);
	}
	private void setLikeSeries(MatchMode matchMode) {		
		this.likeseries = matchMode;
	}
	public java.lang.String getSeries() {
		return this.series;
	}
	
	public void setSeries(java.lang.String value) {		
		this.series = value;
		this.isSeries = true;
	}
	public boolean hasSeries() {
		return this.isSeries;
	}
	public java.lang.String getNotEqSeries() {
		return this.notEqSeries;
	}
	public void setNotEqSeries(java.lang.String series) {
		this.notEqSeries = series;
		this.isNotEqSeries = true;
	}
	public boolean hasNotEqSeries() {
		return this.isNotEqSeries;
	}
	// IN or notIN
	private List<java.lang.String>	inCriterionSeries;
	private List<java.lang.String>	notInCriterionSeries;
	public void setInSeries(boolean isIn,List<java.lang.String> seriess){
		if(isIn){
			inCriterionSeries = seriess;
		}else{
			notInCriterionSeries = seriess;
		}
	}
	public List<java.lang.String> getInSeries() {
		return inCriterionSeries;
	}
	public List<java.lang.String> getNotInSeries() {
		return notInCriterionSeries;
	}
	
	//Null or NotNull
	private Boolean nullCriterionSeries;
	public void setNullSeries(boolean isNull){
			nullCriterionSeries = isNull;
	}
	public Boolean getNullSeries(){
		return nullCriterionSeries;
	} 
	
	public MatchMode getLikeToken() {
		return this.liketoken;
	}
	public String getLikeTokenWithStart() {
		return this.likeTokenWithStart;
	}
	public void setLikeTokenWithStart(String token) {	
		setToken(token);
		setLikeToken(MatchMode.START);
	}
	public String getLikeTokenWithEnd() {
		return this.likeTokenWithEnd;
	}
	public void setLikeTokenWithEnd(String token) {	
		setToken(token);
		setLikeToken(MatchMode.END);
	}
	public String getLikeTokenWithExact() {
		return this.likeTokenWithExact;
	}
	public void setLikeTokenWithExact(String token) {	
		setToken(token);
		setLikeToken(MatchMode.EXACT);
	}
	public String getLikeTokenWithAnywhere() {
		return this.likeTokenWithAnywhere;
	}
	public void setLikeTokenWithAnywhere(String token) {	
		setToken(token);
		setLikeToken(MatchMode.ANYWHERE);
	}
	private void setLikeToken(MatchMode matchMode) {		
		this.liketoken = matchMode;
	}
	public java.lang.String getToken() {
		return this.token;
	}
	
	public void setToken(java.lang.String value) {		
		this.token = value;
		this.isToken = true;
	}
	public boolean hasToken() {
		return this.isToken;
	}
	public java.lang.String getNotEqToken() {
		return this.notEqToken;
	}
	public void setNotEqToken(java.lang.String token) {
		this.notEqToken = token;
		this.isNotEqToken = true;
	}
	public boolean hasNotEqToken() {
		return this.isNotEqToken;
	}
	// IN or notIN
	private List<java.lang.String>	inCriterionToken;
	private List<java.lang.String>	notInCriterionToken;
	public void setInToken(boolean isIn,List<java.lang.String> tokens){
		if(isIn){
			inCriterionToken = tokens;
		}else{
			notInCriterionToken = tokens;
		}
	}
	public List<java.lang.String> getInToken() {
		return inCriterionToken;
	}
	public List<java.lang.String> getNotInToken() {
		return notInCriterionToken;
	}
	
	//Null or NotNull
	private Boolean nullCriterionToken;
	public void setNullToken(boolean isNull){
			nullCriterionToken = isNull;
	}
	public Boolean getNullToken(){
		return nullCriterionToken;
	} 
	
	public java.time.LocalDateTime getLastUsedBegin() {
		return this.lastUsedBegin;
	}
	
	public void setLastUsedBegin(java.time.LocalDateTime value) {
		this.lastUsedBegin = value;
		this.isLastUsedBegin = true;
	}	
	
	public java.time.LocalDateTime getLastUsedEnd() {
		return this.lastUsedEnd;
	}
	
	public void setLastUsedEnd(java.time.LocalDateTime value) {
		this.lastUsedEnd = value;
		this.isLastUsedEnd = true;
	}
	public boolean hasLastUsedBegin() {
		return this.isLastUsedBegin;
	}
	public boolean hasLastUsedEnd() {
		return this.isLastUsedEnd;
	}	
	public java.time.LocalDateTime getLastUsed() {
		return this.lastUsed;
	}
	
	public void setLastUsed(java.time.LocalDateTime value) {		
		this.lastUsed = value;
		this.isLastUsed = true;
	}
	public boolean hasLastUsed() {
		return this.isLastUsed;
	}
	public java.time.LocalDateTime getNotEqLastUsed() {
		return this.notEqLastUsed;
	}
	public void setNotEqLastUsed(java.time.LocalDateTime lastUsed) {
		this.notEqLastUsed = lastUsed;
		this.isNotEqLastUsed = true;
	}
	public boolean hasNotEqLastUsed() {
		return this.isNotEqLastUsed;
	}
	// IN or notIN
	private List<java.time.LocalDateTime>	inCriterionLastUsed;
	private List<java.time.LocalDateTime>	notInCriterionLastUsed;
	public void setInLastUsed(boolean isIn,List<java.time.LocalDateTime> lastUseds){
		if(isIn){
			inCriterionLastUsed = lastUseds;
		}else{
			notInCriterionLastUsed = lastUseds;
		}
	}
	public List<java.time.LocalDateTime> getInLastUsed() {
		return inCriterionLastUsed;
	}
	public List<java.time.LocalDateTime> getNotInLastUsed() {
		return notInCriterionLastUsed;
	}
	
	//Null or NotNull
	private Boolean nullCriterionLastUsed;
	public void setNullLastUsed(boolean isNull){
			nullCriterionLastUsed = isNull;
	}
	public Boolean getNullLastUsed(){
		return nullCriterionLastUsed;
	} 
	
	private List<String> listOrderAsc = new ArrayList<>();
	private List<String> listOrderDesc = new ArrayList<>();

	public void setOrderAsc(String fdName) {
		listOrderAsc.add(fdName);
	}

	public void setOrderDec(String fdName) {
		listOrderDesc.add(fdName);
	}

	public List<String> getOrderAscList() {
		return listOrderAsc;
	}

	public List<String> getOrderDecList() {
		return listOrderDesc;
	}
	
	
	/**
	 * 获取查询条件
	 */
	public Specification<PersistentLogins> createSpecification() {
		Specification<PersistentLogins> example = (root, query, criteriaBuilder) -> {
			List<Order> orders = new ArrayList<>();
			for (String asc : this.getOrderAscList()) {
				orders.add(criteriaBuilder.asc(root.get(asc)));
			}
			for (String desc : this.getOrderDecList()) {
				orders.add(criteriaBuilder.desc(root.get(desc)));
			}
			query.orderBy(orders);
			List<Predicate> predicates = createQuery(root, this, criteriaBuilder);
			hookQuery(root, criteriaBuilder,predicates);
			return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
		};
		return example;
	}
	/**
	 * <p>
	 * <p>自定义的方法时候实现此方法即可(内部类方式使用即可)
	 * <p>使用方法: predicates.add(criteriaBuilder.equal(root.get("biaoqian").as(String.class), "value"));
	 * @param root
	 * @param query
	 * @param criteriaBuilder
	 * @param predicates
	 */
	public void hookQuery(Root<PersistentLogins> root, CriteriaBuilder criteriaBuilder,List<Predicate> predicates) {}
	/**
	 * 组装query对象
	 * 
	 * @param root
	 * @param PersistentLoginsQuery
	 * @param criteriaBuilder
	 * @return
	 */
	private List<Predicate> createQuery(Root<PersistentLogins> root, PersistentLoginsQuery query, CriteriaBuilder criteriaBuilder) {
		List<Predicate> predicates = new ArrayList<Predicate>();
		/**
		 * usernameExpression
		 */
		Expression<java.lang.String> usernameExpression = root.get(PersistentLogins.PROP_USERNAME).as(java.lang.String.class);
		if (query.hasUsername()) {
			java.lang.String value = query.getUsername();
			if (query.getLikeUsername() != null) {
				predicates.add(criteriaBuilder.like(usernameExpression, query.getLikeUsername().toMatchString(value)));
			} else {
				predicates.add(criteriaBuilder.equal(usernameExpression, value));
			}
		}
		if (query.hasNotEqUsername()) {
			java.lang.String value = query.getNotEqUsername();
			predicates.add(criteriaBuilder.notEqual(usernameExpression, value));
		}
		
		if (query.getInUsername() != null) {
			predicates.add(usernameExpression.in(query.getInUsername()));
		}
		if (query.getNotInUsername() != null) {
			predicates.add(criteriaBuilder.not(usernameExpression.in(query.getInUsername())));
		}
		if (query.getNullUsername() != null) {
			if (query.getNullUsername()) {
				predicates.add(criteriaBuilder.isNull(usernameExpression));
			} else {
				predicates.add(criteriaBuilder.isNotNull(usernameExpression));
			}
		}
		/**
		 * seriesExpression
		 */
		Expression<java.lang.String> seriesExpression = root.get(PersistentLogins.PROP_SERIES).as(java.lang.String.class);
		if (query.hasSeries()) {
			java.lang.String value = query.getSeries();
			if (query.getLikeSeries() != null) {
				predicates.add(criteriaBuilder.like(seriesExpression, query.getLikeSeries().toMatchString(value)));
			} else {
				predicates.add(criteriaBuilder.equal(seriesExpression, value));
			}
		}
		if (query.hasNotEqSeries()) {
			java.lang.String value = query.getNotEqSeries();
			predicates.add(criteriaBuilder.notEqual(seriesExpression, value));
		}
		
		if (query.getInSeries() != null) {
			predicates.add(seriesExpression.in(query.getInSeries()));
		}
		if (query.getNotInSeries() != null) {
			predicates.add(criteriaBuilder.not(seriesExpression.in(query.getInSeries())));
		}
		if (query.getNullSeries() != null) {
			if (query.getNullSeries()) {
				predicates.add(criteriaBuilder.isNull(seriesExpression));
			} else {
				predicates.add(criteriaBuilder.isNotNull(seriesExpression));
			}
		}
		/**
		 * tokenExpression
		 */
		Expression<java.lang.String> tokenExpression = root.get(PersistentLogins.PROP_TOKEN).as(java.lang.String.class);
		if (query.hasToken()) {
			java.lang.String value = query.getToken();
			if (query.getLikeToken() != null) {
				predicates.add(criteriaBuilder.like(tokenExpression, query.getLikeToken().toMatchString(value)));
			} else {
				predicates.add(criteriaBuilder.equal(tokenExpression, value));
			}
		}
		if (query.hasNotEqToken()) {
			java.lang.String value = query.getNotEqToken();
			predicates.add(criteriaBuilder.notEqual(tokenExpression, value));
		}
		
		if (query.getInToken() != null) {
			predicates.add(tokenExpression.in(query.getInToken()));
		}
		if (query.getNotInToken() != null) {
			predicates.add(criteriaBuilder.not(tokenExpression.in(query.getInToken())));
		}
		if (query.getNullToken() != null) {
			if (query.getNullToken()) {
				predicates.add(criteriaBuilder.isNull(tokenExpression));
			} else {
				predicates.add(criteriaBuilder.isNotNull(tokenExpression));
			}
		}
		/**
		 * lastUsedExpression
		 */
		Expression<java.time.LocalDateTime> lastUsedExpression = root.get(PersistentLogins.PROP_LAST_USED).as(java.time.LocalDateTime.class);
		if(query.hasLastUsedBegin() && query.getLastUsedBegin()!= null){
			if(!query.hasLastUsedEnd() || query.getLastUsedEnd() == null){
				predicates.add(criteriaBuilder.greaterThan(lastUsedExpression, query.getLastUsedBegin()));
			}else{
				predicates.add(criteriaBuilder.between(lastUsedExpression, query.getLastUsedBegin(), query.getLastUsedEnd()));
			}			
		}
		if(query.hasLastUsedEnd() && query.getLastUsedEnd()!=null){
			if(!query.hasLastUsedBegin() || query.getLastUsedBegin() == null){
				predicates.add(criteriaBuilder.lessThan(lastUsedExpression, query.getLastUsedBegin()));
			}
		}							
		if (query.hasLastUsed()) {
			java.time.LocalDateTime value = query.getLastUsed();
			if( value != null){
				predicates.add(criteriaBuilder.equal(lastUsedExpression, value));					
			}
		}
		if (query.hasNotEqLastUsed()) {
			java.time.LocalDateTime value = query.getNotEqLastUsed();
			predicates.add(criteriaBuilder.notEqual(lastUsedExpression, value));
		}
		
		if (query.getInLastUsed() != null) {
			predicates.add(lastUsedExpression.in(query.getInLastUsed()));
		}
		if (query.getNotInLastUsed() != null) {
			predicates.add(criteriaBuilder.not(lastUsedExpression.in(query.getInLastUsed())));
		}
		if (query.getNullLastUsed() != null) {
			if (query.getNullLastUsed()) {
				predicates.add(criteriaBuilder.isNull(lastUsedExpression));
			} else {
				predicates.add(criteriaBuilder.isNotNull(lastUsedExpression));
			}
		}
		return predicates;
	}
	public String toString() {
		return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE);
	}
	
}

